package org.biogroovy.eutils

import org.biogroovy.net.URLFactory
import org.biogroovy.net.URLMap;
import org.biogroovy.util.*;
import javax.xml.parsers.DocumentBuilderFactory
import org.w3c.dom.Node;


/**
 * This class is responsible for making URLs suitable for calling EUtils services.
 * For more information on EUtils goto: 
 */
public class EUtilsURLFactory extends URLFactory{
	
	/** The base URL used to fetch data from the EUtils databases */
    public static final String EFETCH = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi";
    
	/** The base URL used to search for records from the EUtils databases */
	public static final String ESEARCH = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi";
    
	/** EInfo provides field names, index term counts, last update, and available links for each Entrez database. */
	public static final String EINFO = "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi"

    /**
     * The NCBI Nucleotide database.
     */
    public static final String DB_NUCLEOTIDE="nucleotide";

    /**
     * The NCBI Protein database.
     */
    public static final String DB_PROTEIN="protein";

    /**
     * The NCBI EntrezGene database.
     */
    public static final String DB_GENE="gene";

    /**
     * The NCBI PubMed database
     */
    public static final String DB_PUBMED="pubmed";

    /**
     * The NCBI PubMed Central database containing open access articles.
     */
    public static final String DB_PMC="pmc";

    /**
     * The Johns Hopkins Online Mendelian Inheritance in Man database.
     */
    public static final String DB_OMIM="omim";
    
	
    /**
     * This method gets a FASTA file for the accession, and writes
     * the contents to the output file.  If th e output file parameter
     * is null then the file is written out to a file called &lt;accession&gt;.fasta
     * @param database  The name of the database  (one of the DB_ constants defined
     * 					in the class.
     * @param accession  Either a single accession or multiple comma-delimited accessions.
     * @param outputFile  The output file (may be null).
     */
    public static def getFasta(String database, String accession, String outputFile){
        if (outputFile == null){
            if (accession.indexOf(",") == -1){
                outputFile = accession + ".fasta";
            }
            else {
                String[] accArray = accession.split(",");
                outputFile = accArray[0] + ".fasta";
            }
        }
		
        // get the URL
        String url = getURL(EFETCH, [db:database,id:accession,rettype:'fasta' ]);
		
        // download the file
        FileUtil.downloadText(url, new File(outputFile));
    }
	 
    /**
     * This method gets the XML for a particular NCBI Database, and accession.
     * If an output file is specified, then the XML is saved to the output file.
     * @param database  The name of the database  (one of the DB_ constants defined
     * 					in the class.
     * @param accession  Either a single accession or multiple comma-delimited accessions.
     * @param outputFile  The output file (may be null).
     * @deprecated use the appropriate IReader, or IFetcher implementation.
     */
    public static Node getXML(String database, String accession, String outputFile){
        if (outputFile == null){
            if (accession.indexOf(",") == -1){
                outputFile = accession + ".xml";
            }
            else {
                String[] accArray = accession.split(",");
                outputFile = accArray[0] + ".xml";
            }
        }
			
        // get the URL
        String url = getURL(EFETCH, [db:database,id:accession,rettype:'xml' ]);
		File outFile = new File(outputFile);
	    FileUtil.downloadText(url, outFile);
		def builder     = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        def root = (Node)builder.parse(new FileInputStream(outFile))?.getDocumentElement();
		return root;
    }
	
	/**
	 * This method fetches the XML for a given accession.
	 * @param database	One of the database constants defined in this class.
	 * @param accession	The accession of the gene, protein, transcript.
	 * @return			a org.w3c.dom.Node object representing the root of the document.
	 * @deprecated use the appropriate IReader, IFetcher implementation
	 */
	public static Node getXML(String database, String accession){
		return getURLasXML(EFETCH, [db:database,id:accession,rettype:'xml' ]);
	}
	
	/**
	 * This method searches the selected database for a given search term,
	 * and returns the search results as XML.
	 * @param database		One of the database constants defined in this class.
	 * @param searchTerm	The search term/expression.
	 * @return				a org.w3c.dom.Node object representing the root of the document. 
	 * @deprecated use the appropriate IReader, IFetcher implementation
	 */
	public static Node searchXML(String database, String searchTerm){
		return getURLasXML(ESEARCH, [db:database, term:searchTerm]);
	}

	
}
